#!/usr/bin/env lua
-- Alternative for OpenWrt's /sbin/wifi.
-- Copyright Not Reserved.
-- Hua Shao <nossiac@163.com>

package.path = '/lib/wifi/?.lua;'..package.path

local mtkwifi = require("mtkwifi")
local nixio = require("nixio")

function usage()
	print("wifi <up|down|reset|reload|restart|status> [devname]")
end


function wifi_common_up(devname)
	nixio.syslog("debug", "wifi_common_up "..tostring(devname))

	-- need to find out the vif prefix for this device
	for _,vif in ipairs(string.split(mtkwifi.read_pipe("ls /sys/class/net"), "\n"))
	do
		if string.match(vif, "ra%a-%d+") then
			os.execute("ifconfig "..vif.." up")
		end
	end
	for _,vif in ipairs(string.split(mtkwifi.read_pipe("ls /sys/class/net"), "\n"))
	do
		if string.match(vif, "apcli%a-%d+") then
			os.execute("ifconfig "..vif.." up")
		end
	end

	if devname then
		os.execute("rm -f /tmp/mtk/wifi/"..devname.."*.need_reload")
	else
		os.execute("rm -f /tmp/mtk/wifi/*.need_reload")
	end
end


function wifi_common_down(devname)
	nixio.syslog("debug", "wifi_common_down "..tostring(devname))

	-- need to find out the vif prefix for this device
	for _,vif in ipairs(string.split(mtkwifi.read_pipe("ls /sys/class/net"), "\n"))
	do
		if string.match(vif, "apcli%d+")
		or string.match(vif, "apclii%d+") then
			os.execute("ifconfig "..vif.." down")
		end
	end
	for _,vif in ipairs(string.split(mtkwifi.read_pipe("ls /sys/class/net"), " "))
	do
		if string.match(vif, "ra%d+")
		or string.match(vif, "rai%d+")
		or string.match(vif, "rae%d+")
		or string.match(vif, "rax%d+") then
			os.execute("ifconfig "..vif.." down")
		end
	end
end

function wifi_common_restart(devname)
        nixio.syslog("debug", "wifi_common_restart "..tostring(devname))
        wifi_common_up()
        wifi_common_down()
end

function wifi_common_reload(devname)
	nixio.syslog("debug", "wifi_common_reload "..tostring(devname))
	wifi_common_up()
	wifi_common_down()
end

function wifi_common_reset(devname)
	nixio.syslog("debug", "wifi_common_reset called!")
	local curpath = "/etc/wireless/"
	if devname then
		curpath = curpath..devname.."/"
	end
	local defpath = "/rom"..defpath
	if mtkwifi.exists(defpath) then
		os.execute("rm -rf "..curpath)
		os.execute("cp -rf "..defpath.." "..curpath)
		wifi_common_reload()
	else
		nixio.syslog("debug", defpath.." missing, unable to reset!")
	end
end

function wifi_common_status(devname)
	nixio.syslog("debug", "wifi_common_status "..tostring(devname))
	print(mtkwifi.read_pipe("iwconfig"))
	print(mtkwifi.read_pipe("ifconfig -a"))
end

function wifi_common_detect(devname)
	nixio.syslog("debug", "wifi_common_detect "..tostring(devname))
	local devs = mtkwifi.getdevs()
	for _,dev in ipairs(devs) do
		print("config wifi-device "..dev.devname..
			"\n\toption type "..dev.devname..
			"\n\toption vendor ralink"..
			"\n\toption channel "..dev.Channel)
		for _,vif in ipairs(dev.vifs) do
			print("\nconfig wifi-iface"..
				"\n\toption device"..dev.devname..
				"\n\toption ifname"..vif.vifname..
				"\n\toption network lan"..
				"\n\toption mode ap")
		end
	end
end

for _,f in ipairs(string.split(mtkwifi.read_pipe("find /lib/wifi/ -name \"*.lua\" 2>/dev/null"), "\n")) do
	dofile(f)
end

function wifi(cmd, devname)
	local mtkwifi = require("mtkwifi")
	local devs, l1parser = mtkwifi.__get_l1dat()
	l1parser.creat_link_for_nvram()
	if not devs or not l1parser then
		return wifi_orig(cmd, devname)
	end

	if devname then
		local dev = devs.devname_ridx[devname]
		local compatname = dev.init_compatible
		assert(compatname)

		if _G[compatname.."_"..cmd] then
			nixio.syslog("info", "call "..compatname.."_"..cmd.."("..devname..")")
			_G[compatname.."_"..cmd](devname)
		end
	else
		-- if devname not specified
		if cmd == "restart" or cmd == "reload" then
			local tab_compatname = {}
			for key, dev in pairs(devs.devname_ridx) do
				tab_compatname[key] = dev.init_compatible
			end
			local tab_rp = {}
			for key,val in pairs(tab_compatname) do
				tab_rp[val] = true
			end

			for dev, val in pairs(tab_rp) do
				nixio.syslog("info", "call "..dev.."_"..cmd)
				_G[dev.."_"..cmd]()
			end
		else
			for devname, dev in mtkwifi.__spairs(devs.devname_ridx) do
				local compatname = dev.init_compatible
				nixio.syslog("info", "call "..compatname.."_"..cmd.."("..devname..")")
				_G[compatname.."_"..cmd](devname)
			end
		end
	end
end

function wifi_orig(cmd,devname)
	print("wifi_orig",cmd,devname)
	local relname = nil
	if devname then
		relname = string.split(devname,".")[1]
	end

	if relname then
		if _G[relname.."_"..cmd] then
			nixio.syslog("info", "call "..relname.."_"..cmd.."("..devname..")")
			_G[relname.."_"..cmd](devname)
		end
	else
		local devinfo = mtkwifi.search_dev_and_profile()
		local done = {}
		for __devname in pairs(devinfo) do
			local __relname = string.split(__devname,".")[1]
			repeat
				-- common case
				if done[__relname] then break else done[__relname] = true end
				if _G[__relname.."_"..cmd] then
					nixio.syslog("info", "call "..__relname.."_"..cmd.."("..__devname..")")
					_G[__relname.."_"..cmd](__devname)
					break
				end
				-- try shell
				local dev_shell = "/lib/wifi/"..__relname..".sh"
				if mtkwifi.exists(dev_shell) then
					local cmd = "source "..dev_shell.."; "..__relname.."_"..cmd.." > /dev/null"
					nixio.syslog("info", cmd)
					if os.execute(cmd) ~= 0 then
						nixio.syslog("err", cmd)
					end
					break
				end
				-- fall back on common api
				nixio.syslog("info", "no scripts for "..__relname.." found, fall back on common api!")
				_G["wifi_common_"..cmd](__devname)
			until true
		end
	end
end

cmd = arg[1]
dev = arg[2]

if cmd == "up"
or cmd == "down"
or cmd == "status"
or cmd == "detect"
or cmd == "reload"
or cmd == "restart"
or cmd == "reset" then
	wifi(cmd, dev)
elseif cmd == "reload_legacy" then
	nixio.syslog("info", "legacy command "..cmd)
	wifi("reload", dev)
else
	usage()
end

